#include "Logger.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <ctime>
#include "../Settings/Settings.h"

const std::string Logger::fileName_  = "log.txt";

void log(const std::string &message)
{
  Logger::getInstance().log(message);
}

void log(const std::string &message, LEVEL level)
{
  Logger::getInstance().log(message, level);
}

void log(const double message)
{ 
  Logger::getInstance().log(message);
}

void log(const double message, LEVEL level)
{
  Logger::getInstance().log(message, level);
}

Logger::Logger()
{
  defaultLevel_ = NONE;
  
  std::string defaultString = Settings::getInstance().get("DEFAULT_LEVEL");
  if (defaultString == "CRITICAL")
  {
    defaultLevel_ = CRITICAL;
  }
  else if (defaultString == "INFO")
  {
    defaultLevel_ = INFO;
  }
  else if (defaultString == "DEBUG")
  {
    defaultLevel_ = DEBUG;
  }
  else if (defaultString == "NONE") 
  {
    defaultLevel_ = NONE;
  }
}

void Logger::log(const std::string &message)
{
  Logger::log(message, defaultLevel_);
}

void Logger::log(const std::string &message, LEVEL level)
{
  time_t seconds = time(NULL);
  tm* timeInfo = localtime(&seconds);
  
 
  switch(level)
  {
  case (CRITICAL):
  {
    std::cout << asctime(timeInfo);
    std::cout << message << std::endl << std::endl;
    break;
  }
  case (INFO):
  {
    std::ofstream f;
    f.open(fileName_.c_str(), std::ios::app);
    f << asctime(timeInfo);
    f << message << std::endl << std::endl;
    f.close();
    break;
  }
  case (DEBUG):
  {
    std::ofstream f;
    f.open(fileName_.c_str(), std::ios::app);
    f << asctime(timeInfo);
    f << message << std::endl << std::endl;
    f.close();
    break;
  }
  case (NONE):
  {
    break;
  }
  }
}

void Logger::log(const double message)
{ 
  Logger::log(message, defaultLevel_);
}

void Logger::log(const double message, LEVEL level)
{
  std::stringstream messageStream;
  messageStream << message;
  Logger::log(messageStream.str(), level);
}

Logger& Logger::getInstance()
{
  static Logger instance_;
  
  return instance_;
  
}
